package com.tengju.bff.interfaces.app.common.facade;


import com.fasterxml.jackson.core.type.TypeReference;
import com.google.common.collect.Lists;
import com.tengju.bff.interfaces.app.common.assembler.AppBannerAssembler;
import com.tengju.bff.interfaces.app.common.assembler.UserProtocolAssembler;
import com.tengju.bff.interfaces.app.common.vo.*;
import com.tengju.bff.interfaces.shared.InterfaceCode;
import com.tengju.bff.interfaces.shared.InterfaceException;
import com.tengju.bff.interfaces.shared.servlet.ServletContextUtil;
import com.tengju.bff.interfaces.shared.servlet.UserServletContext;
import com.tengju.data.application.profit.MarketBonusService;
import com.tengju.data.domain.model.report.AchievementBonusDateConfig;
import com.tengju.data.domain.model.report.AchievementBonusLogRepository;
import com.tengju.data.domain.model.service.AchievementBonusDateConfigService;
import com.tengju.data.domain.model.user.UserIdCode;
import com.tengju.data.domain.shared.Month;
import com.tengju.payment.domain.shard.JsonUtil;
import com.tengju.support.application.shared.ApplicationException;
import com.tengju.support.application.shared.ApplicationExceptionCode;
import com.tengju.support.domain.model.resource.Resource;
import com.tengju.support.domain.model.resource.ResourceOrientation;
import com.tengju.support.domain.model.resource.ResourceRepository;
import com.tengju.support.domain.model.resource.StarLevel;
import com.tengju.user.application.protocol.UserProtocolService;
import com.tengju.user.domain.model.protocol.ProtocolType;
import com.tengju.user.domain.model.protocol.ProtocolVersion;
import com.tengju.user.domain.model.user.*;
import com.tengju.user.domain.service.RemoteUserService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

import static com.tengju.data.domain.shared.DateUtil.DATE_TIME_FORMAT;

@Slf4j
@Component
@RequiredArgsConstructor(onConstructor_ = {@Autowired})
public class CommonFacade {

    private final UserInfoRepository userInfoRepository;
    private final UserProtocolService userProtocolService;
    private final MarketBonusService marketBonusService;
    private final RemoteUserService remoteUserService;
    private final ResourceRepository resourceRepository;
    private final AchievementBonusLogRepository achievementBonusLogRepository;
    private final AchievementBonusDateConfigService achievementBonusDateConfigService;



    @Value("${app.start.companyName}")
    private String companyName;
    @Value("${app.start.taxId}")
    private String taxId;
    @Value("${app.start.companyAddress}")
    private String companyAddress;
    @Value("${app.start.companyTel}")
    private String companyTel;
    @Value("${app.start.bankName}")
    private String bankName;
    @Value("${app.start.bankCard}")
    private String bankCard;
    @Value("${app.start.serviceCharge.limitMoney}")
    private String limitMoney;
    @Value("${app.start.serviceCharge.ruleList}")
    private String rule;
    @Value("${app.start.serviceCharge.applyAndSendTime}")
    private String applyAndSendTime;
    @Value("#{${app.common.date.show.status.map}}")
    private Map<String,Boolean> dateShowStatusMap;

    @Value("#{${app.start.recipient}}")
    private Map<String,String> recipientMap;

    public boolean agreeProto(List<Integer> protocolIds) throws InterfaceException {

        UserServletContext servletContext = ServletContextUtil.getServletContext();
        UserId userId = servletContext.getUserId();

        UserInfo userInfo = userInfoRepository.getByUserId(userId);

        if (userInfo == null) {
            throw new InterfaceException(InterfaceCode.USER_NOT_EXIST);
        }

        List<ProtocolType> protocolTypes = UserProtocolAssembler.protocolIdToModel(protocolIds);

        List<ProtocolVersion> confirmVersion = userProtocolService.getVersion(protocolTypes);

        return userProtocolService.confirmProtocol(userInfo, confirmVersion);

    }

    public AppHomePageVO appHomePage() {

        UserServletContext servletContext = ServletContextUtil.getServletContext();
        UserId userId = servletContext.getUserId();

        // 获取市场补贴日期配置信息
        LocalDate curDate = LocalDate.now();
        Month curMonth = new Month(curDate);
        Integer dateKey = curMonth.getMonthInt();
        AchievementBonusDateConfig dateConfig = achievementBonusDateConfigService.queryByCalDateOrDefault(curDate);
        if (!StringUtils.isBlank(dateConfig.getDataKey())) {
            dateKey = Integer.valueOf(dateConfig.getDataKey());
        }

        UserInfo userInfo = userInfoRepository.getByUserId(userId);

        if (userInfo == null) {
            throw ApplicationException.error(ApplicationExceptionCode.INVALID_DATA,"用户不存在");
        }

        UserInfo remoteUserInfo = null;
        if (userInfo.getIdCode() != null) {
            remoteUserInfo = remoteUserService.getByIdCode(userInfo.getIdCode());
        }

        Long idCode = Optional.ofNullable(userInfo.getIdCode())
                .map(com.tengju.user.domain.model.user.UserIdCode::getValue)
                .orElse(null);

        boolean showData = LocalDate.now().isBefore(LocalDate.of(2021,1,1)) || userInfo.showSettleData();

//        BigDecimal totalAdvert = idCode == null  || !showData ? BigDecimal.valueOf(0L) :
//                marketBonusService.calculateAdvertIndex(LocalDate.now(), new UserIdCode(idCode));
        BigDecimal totalAdvert = idCode == null  || !showData ? BigDecimal.valueOf(0L) :
                marketBonusService.calculateAdvertIndexByConfig(dateKey,new UserIdCode(idCode));

        LocalDateTime logTime = null;
        if (idCode != null) {
            logTime = achievementBonusLogRepository.queryMaxLogTime(new UserIdCode(idCode), dateKey);
        }

        
        int totalAdvertIndex = Math.max(totalAdvert.intValue() / 100 * 100, 0);


        return new AppHomePageVO(userInfo.getNickName(),
                userInfo.getHeadImage(),
                idCode,
                totalAdvertIndex,
                dateKey % 100 + "月广告指数",
                logTime == null ? "" : logTime.format(DateTimeFormatter.ofPattern(DATE_TIME_FORMAT)),
                Optional.ofNullable(remoteUserInfo)
                        .map(UserInfo::getAbmLevel)
                        .orElse(null)
        );

    }

    public List<AppBannerVO> getAppBannerInfo(UserId userId) {
        List<Resource> bannerInfoList = resourceRepository.findAll();

        UserInfo userInfo = userInfoRepository.getByUserId(userId);
        StarLevel starLevel = StarLevel.parseByCode(userInfo.getStarLevel());
        ResourceOrientation resourceOrientation = ResourceOrientation.fromStarLevel(starLevel);

        List<Resource> result = Lists.newArrayList();

        for (Resource resource : bannerInfoList) {
            if (resource.getUserOrientation().contains(resourceOrientation)) {
                result.add(resource);
            }

        }

        if (CollectionUtils.isEmpty(result)) {
            return Lists.newArrayList();
        }

        return result.stream().map(AppBannerAssembler::domainToVo).collect(Collectors.toList());
    }

    public AppStartVO appStart() {
        List<Map<String, String>> ruleList = JsonUtil.toList(rule, new TypeReference<>() {
        });
        List<ServiceChargeRuleVO> ruleVOList = Lists.newArrayList();
        if (!CollectionUtils.isEmpty(ruleList)) {
            for (Map<String, String> ruleMap : ruleList) {
                ServiceChargeRuleVO serviceChargeRuleVO = new ServiceChargeRuleVO(ruleMap.get("ratio"),
                        ruleMap.get("rule"),
                        ruleMap.get("example"));
                ruleVOList.add(serviceChargeRuleVO);
            }
        }
        //服务费相关配置
        ServiceChargeConfigVO serviceChargeConfigVO = new ServiceChargeConfigVO(companyName, taxId, companyAddress,
                companyTel, bankName, bankCard, limitMoney, ruleVOList, applyAndSendTime);

        //收件人配置
        RecipientConfigVO recipientConfigVO =
                new RecipientConfigVO(recipientMap.get("name"), recipientMap.get("phone"), recipientMap.get("address"));
        return new AppStartVO(serviceChargeConfigVO,recipientConfigVO);
    }

    public DateRangeVO getDateRangeList(String key) {
        // 控制日期是否展示
        if (dateShowStatusMap.get(key) != null && !dateShowStatusMap.get(key)) {
            return null;
        }
        CommonDateListRangeEnum rangeEnum = CommonDateListRangeEnum.getByKey(key);
        DateRangeVO dateRangeVO = new DateRangeVO();
        // 开始时间
        dateRangeVO.setStartDate(rangeEnum.getStartDate());
        // 结束时间
        LocalDate now = LocalDate.now();
        CommonDateRangeDetial end;
        if (("now").equals(rangeEnum.getEndDate())) {
            end = new CommonDateRangeDetial(now.getYear(), now.getMonthValue(), now.getDayOfMonth());
        } else if (("bonusMonth").equals(rangeEnum.getEndDate())) {
            AchievementBonusDateConfig dateConfig = achievementBonusDateConfigService.queryByCalDateOrDefault(now);
            LocalDate configEndDate = dateConfig.getEndDate() == null ? now : dateConfig.getEndDate();
            end = new CommonDateRangeDetial(configEndDate.getYear(), configEndDate.getMonthValue(), configEndDate.getDayOfMonth());
        } else {
            end = new CommonDateRangeDetial(2099, 12, 31);
        }
        dateRangeVO.setEndDate(end);
        return dateRangeVO;
    }


}
